package com.yuanfeng.goods.util.es;

import com.alibaba.fastjson.JSON;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.Bucket;
import com.aliyun.oss.model.GetObjectRequest;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;
import com.yuanfeng.commoms.dto.base.OssUploadInfoDTO;
import com.yuanfeng.commoms.dto.oos.OssUploadUpdateParamDTO;
import com.yuanfeng.commoms.util.ResponseResult;
import com.yuanfeng.commoms.util.UUIDUtils;
import com.yuanfeng.commoms.util.secverifyapiutil.Base64Utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.stream.FileImageInputStream;
import java.io.*;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

/**
 * 
 * @ClassName: AliyunOSSClientUtil
 * @Description: 阿里云OSS上传文件模块
 * @author wy
 * @date 2017年5月6日 下午6:01:46
 *
 */
@Component
public class AliyunOSSClientUtil {
	// log日志
	private static Logger logger =  LoggerFactory.getLogger(AliyunOSSClientUtil.class);

	// 阿里云API的内或外网域名
    public static String ENDPOINT;
	// 阿里云API的密钥Access Key ID
    public static  String ACCESS_KEY_ID;
	// 阿里云API的密钥Access Key Secret
    public static  String ACCESS_KEY_SECRET;
	// 阿里云API的bucket名称
    public static  String BACKET_NAME;
	// 阿里云API的文件夹名称
    public static  String FOLDER;

    public static final String FORMAT =new SimpleDateFormat("yyyyMMdd").format(new Date());

	public static final String VIDEO_BACKET_NAME = "video";

	public static final String VIDEO_FOLDER = "goods/";

	public static final String WATER_MARK = "goods/";

	public static void deleteFile(String fileName) {
		OSSClient ossClient = AliyunOSSClientUtil.getOSSClient();
		ossClient.deleteObject(BACKET_NAME, VIDEO_FOLDER + fileName);
	}

	public static String uploadFile(MultipartFile file) {
		String url = null;
		OSSClient ossClient = AliyunOSSClientUtil.getOSSClient();
		String fileName = file.getOriginalFilename();
		fileName = String.format("%s.%s", UUIDUtils.getUUID(), fileName.substring(fileName.lastIndexOf(".") + 1));
		try (InputStream inputStream = file.getInputStream()) {
			ObjectMetadata objectMetadata = new ObjectMetadata();
			objectMetadata.setContentLength(inputStream.available());
			objectMetadata.setCacheControl("no-cache");
			objectMetadata.setHeader("Pragma", "no-cache");
			// 指定该Object被下载时的内容编码格式
			objectMetadata.setContentEncoding("utf-8");
			objectMetadata.setContentType(getContentType(fileName));
			objectMetadata.setContentDisposition("inline;filename=" + fileName);
			PutObjectResult putObjectResult = ossClient.putObject(BACKET_NAME, VIDEO_FOLDER + fileName, inputStream,
					objectMetadata);
			// 解析结果
			String resultStr = putObjectResult.getETag();
			logger.info("解析结果:" + JSON.toJSONString(resultStr));

			url = AliyunOSSClientUtil.getUrl(ossClient, AliyunOSSClientUtil.BACKET_NAME, VIDEO_FOLDER + fileName);
			url = url.replace("fkgou-images.oss-cn-qingdao.aliyuncs.com", "oss.fkgou.com").replace("http:", "https:");
			logger.info("访问网址路径:" + url);
		} catch (OSSException oe) {
			logger.info("Error Message: " + oe.getErrorCode());
			logger.info("Error Code:    " + oe.getErrorCode());
			logger.info("Request ID:    " + oe.getRequestId());
			logger.info("Host ID:       " + oe.getHostId());
			return null;
		} catch (IOException e) {
			logger.info("Error Message: " + e.getMessage());
			return null;
		}
		return url;
	}

	/**
	 * 获取阿里云OSS客户端对象
	 * 
	 * @return ossClient
	 */
	public static OSSClient getOSSClient() {
		return new OSSClient(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);
	}

	/**
	 * 创建存储空间
	 * 
	 * @param ossClient  OSS连接
	 * @param bucketName 存储空间
	 * @return
	 */
	public static String createBucketName(OSSClient ossClient, String bucketName) {
		// 存储空间
		final String bucketNames = bucketName;
		if (!ossClient.doesBucketExist(bucketName)) {
			// 创建存储空间
			Bucket bucket = ossClient.createBucket(bucketName);
			logger.info("创建存储空间成功");
			return bucket.getName();
		}
		return bucketNames;
	}

	/**
	 * 上传文件
	 * @param param
	 * @return
	 */
	public static ResponseResult uploadToOss(OssUploadUpdateParamDTO param) {

		OSSClient ossClient = AliyunOSSClientUtil.getOSSClient();
		// 解密
		byte[] decode = Base64Utils.decode(param.getBase64Str().getBytes());


		String name = param.getStreamName();
		if(name.contains(".")) {
			name.substring(name.lastIndexOf("."));
			name = name.substring(name.lastIndexOf("."));
			name = getRandom() + name;
		}else {
			name = getRandom();
		}

		String path = AliyunOSSClientUtil.uploadByteVideoOSS(ossClient, decode, BACKET_NAME,
				name, param.getFileUrl());
		String url = AliyunOSSClientUtil.getUrl(ossClient, AliyunOSSClientUtil.BACKET_NAME, path);
		url = url.replace("http:", "https:");
        ossClient.shutdown();
        logger.debug("getEndpoint>>>>"+param.getEndpoint());
        logger.debug("url>>>>"+url);
		return ResponseResult.success(url);
	}

	// 上传多种类型
	public static String uploadByteVideoOSS(OSSClient ossClient, byte[] b, String bucketName, String fileName,
			String fileUrl) {

		// 以输入流的形式上传文件
		String folder = "";
		folder = fileUrl + FORMAT + "/";
		// 文件名
		fileName = UUIDUtils.getUUID() + fileName;
		logger.info("上传到路径" + folder + fileName);

		Long fileSize = (long) b.length;

		// 创建上传Object的Metadata
		ObjectMetadata metadata = new ObjectMetadata();
		metadata.setContentLength(fileSize);
		// 指定该Object被下载时的网页的缓存行为
		metadata.setCacheControl("no-cache");
		// 指定该Object下设置Header
		metadata.setHeader("Pragma", "no-cache");
		// 指定该Object被下载时的内容编码格式
		metadata.setContentEncoding("utf-8");
		// 文件的MIME，定义文件的类型及网页编码，决定浏览器将以什么形式、什么编码读取文件。如果用户没有指定则根据Key或文件名的扩展名生成，
		// 如果没有扩展名则填默认值application/octet-stream
		metadata.setContentType(getContentType(fileName));
		// 指定该Object被下载时的名称（指示MINME用户代理如何显示附加的文件，打开或下载，及文件名称）
		metadata.setContentDisposition("filename/filesize=" + fileName + "/" + fileSize + "Byte.");

		ossClient.putObject(bucketName, folder + fileName, new ByteArrayInputStream(b), metadata);
		ossClient.shutdown();
		String filepath = folder + fileName;
		return filepath;
	}

	public static String uploadByteVideoOSS2(OSSClient ossClient, byte[] b, String bucketName, String fileName,
			String fileUrl) {

		// 以输入流的形式上传文件
		String folder = "";
		folder = fileUrl + FORMAT + "/";
		// 文件名
		fileName = UUIDUtils.getUUID() + fileName;
		logger.info("上传到路径" + folder + fileName);

		Long fileSize = (long) b.length;

		// 创建上传Object的Metadata
		ObjectMetadata metadata = new ObjectMetadata();
		metadata.setContentLength(fileSize);
		// 指定该Object被下载时的网页的缓存行为
		metadata.setCacheControl("no-cache");
		// 指定该Object下设置Header
		metadata.setHeader("Pragma", "no-cache");
		// 指定该Object被下载时的内容编码格式
		metadata.setContentEncoding("utf-8");
		// 文件的MIME，定义文件的类型及网页编码，决定浏览器将以什么形式、什么编码读取文件。如果用户没有指定则根据Key或文件名的扩展名生成，
		// 如果没有扩展名则填默认值application/octet-stream
		metadata.setContentType(getContentType(fileName));
		// 指定该Object被下载时的名称（指示MINME用户代理如何显示附加的文件，打开或下载，及文件名称）
		metadata.setContentDisposition("filename/filesize=" + fileName + "/" + fileSize + "Byte.");

		ossClient.putObject(bucketName, folder + fileName, new ByteArrayInputStream(b), metadata);
		ossClient.shutdown();
		String filepath = folder + fileName;
		return filepath;
	}

	// 图片转化为byte数组
	public static byte[] image2byte(String path) {
		byte[] data = null;
		FileImageInputStream input = null;
		try {
			input = new FileImageInputStream(new File(path));
			ByteArrayOutputStream output = new ByteArrayOutputStream();
			byte[] buf = new byte[1024];
			int numBytesRead = 0;
			while ((numBytesRead = input.read(buf)) != -1) {
				output.write(buf, 0, numBytesRead);
			}
			data = output.toByteArray();
			output.close();
			input.close();
		} catch (FileNotFoundException ex1) {
			ex1.printStackTrace();
		} catch (IOException ex1) {
			ex1.printStackTrace();
		}
		return data;
	}

	/**
	 * 通过文件名判断并获取OSS服务文件上传时文件的contentType
	 * 
	 * @param fileName 文件名
	 * @return 文件的contentType
	 */
	public static String getContentType(String fileName) {
		// 文件的后缀名
		String fileExtension = fileName.substring(fileName.lastIndexOf("."));
		if (".bmp".equalsIgnoreCase(fileExtension)) {
			return "image/bmp";
		}
		if (".gif".equalsIgnoreCase(fileExtension)) {
			return "image/gif";
		}
		if (".jpeg".equalsIgnoreCase(fileExtension) || ".jpg".equalsIgnoreCase(fileExtension)
				|| ".png".equalsIgnoreCase(fileExtension)) {
			return "image/jpeg";
		}
		if (".html".equalsIgnoreCase(fileExtension)) {
			return "text/html";
		}
		if (".txt".equalsIgnoreCase(fileExtension)) {
			return "text/plain";
		}
		if (".vsd".equalsIgnoreCase(fileExtension)) {
			return "application/vnd.visio";
		}
		if (".ppt".equalsIgnoreCase(fileExtension) || "pptx".equalsIgnoreCase(fileExtension)) {
			return "application/vnd.ms-powerpoint";
		}
		if (".doc".equalsIgnoreCase(fileExtension) || ".docx".equalsIgnoreCase(fileExtension)) {
			return "application/msword";
		}
		if (".xml".equalsIgnoreCase(fileExtension)) {
			return "text/xml";
		}
		if (".mp4".equalsIgnoreCase(fileExtension)) {
			return "video/mp4";
		}
		// 默认返回类型
		return "image/jpeg";
	}

	/**
	 * 获得url链接
	 * @param ossClient
	 * @param bucketName
	 * @param fileName
	 * @return
	 */
	public static String getUrl(OSSClient ossClient, String bucketName, String fileName) {
		// 设置URL过期时间为10年 3600l* 1000*24*365*10
		Date expiration = new Date(System.currentTimeMillis() + 3600L * 1000 * 24 * 365 * 10);
		// 生成URL
		URL url = ossClient.generatePresignedUrl(bucketName, fileName, expiration);
		if (url != null) {
			return url.toString();
		}
		return "获网址路径出错";
	}

	// 上传文件
	public static void uploadFile(OSSClient client, String bucketName, String key, String filename)
			throws OSSException, ClientException, FileNotFoundException {
		File file = new File(filename);

		ObjectMetadata objectMeta = new ObjectMetadata();
		objectMeta.setContentLength(file.length());

		InputStream input = new FileInputStream(file);
		PutObjectResult rs = client.putObject(bucketName, key, input, objectMeta);

	}

	// 下载文件
	public static String downloadFile(String key) throws IOException {
		OSSClient ossClient = getOSSClient();

		String uuid = UUIDUtils.getUUID();

		File file = File.createTempFile(uuid, ".csv");
		String srcPath = file.getAbsolutePath();
		ossClient.getObject(new GetObjectRequest(BACKET_NAME, key), new File(srcPath));

		return srcPath;

	}

	// 测试
	public static void main(String[] args) throws Exception {

		// 初始化OSSClient

		String watermark = "fkgou-images/file/upload/20200310/c8fd4bb139cd4b54b10250881d40ea82.png";
		OSSClient ossClient = AliyunOSSClientUtil.getOSSClient();
		byte[] b1 = AliyunOSSClientUtil.image2byte("D:\\image\\3.png");
		String path = AliyunOSSClientUtil.uploadByteVideoOSS(ossClient, b1, BACKET_NAME, ".png", FOLDER);
		String url = AliyunOSSClientUtil.getUrl(ossClient, BACKET_NAME, path);

		logger.info("访问网址路径:" + url);

	}

	public static String getRandom(){
		Random random = new Random();
		String result="";
		for (int i=0;i<6;i++)
		{
			result+=random.nextInt(10);
		}
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		result = result + sdf.format(new Date());
		return result;
	}

	public static ResponseResult uploadToOssShop(OssUploadInfoDTO param) {

		OSSClient ossClient = AliyunOSSClientUtil.getOSSClient();
		// 解密
		byte[] decode = Base64Utils.decode(param.getBase64Str().getBytes());

		String path = AliyunOSSClientUtil.uploadByteVideoOSS2(ossClient, decode, BACKET_NAME,
				param.getStreamName(), param.getEndpoint());
		String url = AliyunOSSClientUtil.getUrl(ossClient, AliyunOSSClientUtil.BACKET_NAME, path);
//		url = url.replace("http:", "https:");
		ossClient.shutdown();
		logger.debug("getEndpoint>>>>"+param.getEndpoint());
		logger.debug("url>>>>"+url);
		return ResponseResult.success(url);
	}

}